<?php

//$process = new swoole_process(function (\Swoole\Process $worker) {
//    // 子进程逻辑
//    // 通过管道从主进程读取数据
//    $cmd = $worker->read();
//    ob_start();
//    // 执行外部程序并显示未经处理的原始输出，会直接打印输出
//    passthru($cmd);
//    $ret = ob_get_clean() ? : ' ';
//    $ret = trim($ret) . ". worker pid:" . $worker->pid . "\n";
//    // 将数据写入管道
//    $worker->write($ret);
//    $worker->exit(0);  // 退出子进程
//});  // Process 构造函数第三个参数默认为 true，启用管道，如果第二个参数也设置为 true，则在子进程中可以通过 echo 将数据写入管道
//
//// 启动进程
//$process->start();
//// 从主进程将通过管道发送数据到子进程
//$process->write('php --version');
//// 从子进程读取返回数据并打印
//$msg = $process->read();
//echo 'result from worker: ' . $msg;


// 异步通信逻辑
//$process = new swoole_process(function (\Swoole\Process $worker) {
//    // 子进程逻辑
//    swoole_event_add($worker->pipe, function ($pipe) use ($worker) {
//        // 通过管道从主进程读取数据
//        $cmd = $worker->read();
//        ob_start();
//        // 执行外部程序并显示未经处理的原始输出，会直接打印输出
//        passthru($cmd);
//        $ret = ob_get_clean() ?: ' ';
//        $ret = trim($ret) . ". worker pid:" . $worker->pid . "\n";
//        // 将数据写入管道
//        $worker->write($ret);
//        $worker->exit(0);  // 退出子进程
//    });
//    // 其它子进程逻辑
//});  // Process 构造函数第三个参数默认为 true，启用管道，如果第二个参数也设置为 true，则在子进程中可以通过 echo 将数据写入管道
//
//// 启动进程
//$process->start();
//// 从主进程将通过管道发送数据到子进程
//$process->write('php --version');
//// 从子进程读取返回数据并打印
//$msg = $process->read();
//echo 'result from worker: ' . $msg;


//消息队列
//$process = new swoole_process(function (\Swoole\Process $worker) {
//    // 子进程逻辑
//    // 从消息队列读取数据
//    $cmd = $worker-> pop();
//    echo "Message from master process: " . $cmd . "\n";
//    ob_start();
//    // 执行外部程序并显示未经处理的原始输出，会直接打印输出
//    passthru($cmd);
//    $ret = ob_get_clean() ? : ' ';
//    $ret = trim($ret) . ". worker pid:" . $worker->pid . "\n";
//    // 将返回消息推送到消息队列
//    $worker->push($ret);
//    $worker->exit(0);  // 退出子进程
//}, false, false);  // 关闭管道
//// 调用 useQueue 表示使用消息队列进行进程间通信
//// 消息队列与管道通信不能共存
//// 第一个参数表示消息队里的 key，第二个参数表示通信模式，2 表示争抢模式
//// 使用争抢模式进行通信时，哪个子进程先读取到消息先消费，因此无法实现与指定子进程的通信
//// 消息队列不支持事件循环，因此引入了 \Swoole\Process::IPC_NOWAIT 表示以非阻塞模式进行通信
//$process->useQueue(1, 2 | \Swoole\Process::IPC_NOWAIT);
//// 从主进程将将命令推送到消息队列
//$process->push('php --version');
//// 从消息队列读取返回消息
//$msg = $process->pop();
//echo 'Message from worker process: ' . $msg;
//
//// 启动子进程
//$process->start();
//
//swoole_process::wait();   // 要调用这段代码，否则子进程中的 push 或 pop 可能会报错


// redis 进程池实现
//$workerNum = 5;
//$pool = new Swoole\Process\Pool($workerNum);
//
//$pool->on("WorkerStart", function ($pool, $workerId) {
//    echo "Worker#{$workerId} is started\n";
//    $redis = new Redis();
//    $redis->pconnect('127.0.0.1', 6379);
//    $key = "key1";
//    while (true) {
//        $msgs = $redis->brpop($key, 2);
//        if ( $msgs == null)
//            continue;
//        var_dump($msgs);
//        echo "Processed by Worker#{$workerId}\n";
//    }
//});
//
//$pool->on("WorkerStop", function ($pool, $workerId) {
//    echo "Worker#{$workerId} is stopped\n";
//});
//
//$pool->start();



// Swoole\Table 实现Swoole多进程数据共享
// 初始化一个容量为 1024 的 Swoole Table
//$table = new \Swoole\Table(1024);
//// 在 Table 中新增 id 列
//$table->column('id', \Swoole\Table::TYPE_INT);
//// 在 Table 中新增 name 列，长度为 50
//$table->column('name', \Swoole\Table::TYPE_STRING, 10);
//// 在 Table 中新泽 score 列
//$table->column('score', \Swoole\Table::TYPE_FLOAT);
//// 创建这个 Swoole Table
//$table->create();
//
//
//// 设置 Key-Value 值
//$table->set('student-1', ['id' => 1, 'name' => '学小君', 'score' => 80]);
//$table->set('student-2', ['id' => 2, 'name' => '学院君', 'score' => 90]);
//
//// 如果指定 Key 值存在则打印对应 Value 值
//if ($table->exist('student-1')) {
//    echo "Student-" . $table->get('student-1', 'id') . ':' . $table->get('student-1', 'name') . ":" .
//        $table->get('student-1', 'score') . "\n";
//}
//
//// 自增操作
//$table->incr('student-2', 'score', 5);
//// 自减操作
//$table->decr('student-2', 'score', 5);
//
//// 表中总记录数
//$count = $table->count();
//
//// 删除指定表记录
//$table->del('student-1');



//swoole 实现携程
$server = new \Swoole\Http\Server('127.0.0.1', 9588);

$server->on('Request', function ($request, $response) {

    var_dump(time());

    $mysql = new Swoole\Coroutine\MySQL();
    $mysql->connect([
        'host'     => '127.0.0.1',
        'user'     => 'root',
        'password' => '123456',
        'database' => 'yii',
    ]);
    $mysql->setDefer();
    $mysql->query('select sleep(3)');

    var_dump(time());

    $redis1 = new \Swoole\Coroutine\Redis();
    $redis1->connect('127.0.0.1', 6379);
    $redis1->setDefer();
    $redis1->set('hello', 'world');

    var_dump(time());

    $redis2 = new \Swoole\Coroutine\Redis();
    $redis2->connect('127.0.0.1', 6379);
    $redis2->setDefer();
    $redis2->get('hello');

    $result1 = $mysql->recv();
    $result2 = $redis2->recv();

    var_dump($result1, $result2, time());

    $response->end('Request Finish: ' . time());
});

$server->start();